#ifndef __CC_THREAD__
#define __CC_THREAD__
#include "cc_config.h"
#include "cc_portable.h"

typedef struct
{
  char name[CC_CONFIG_TID_NAME_MAX];
  cc_tid tid;
  uint32_t stack_size;
  uint8_t prio;
  cc_tid_fun fun;
  cc_list_node node;
  uint8_t is_create;

} cc_thread;

#define CC_THREAD_STATE_RUNNING eRunning
#define CC_THREAD_STATE_READY eReady
#define CC_THREAD_STATE_BLOCK eBlocked
#define CC_THREAD_STATE_SUSPEND eSuspended
#define CC_THREAD_STATE_DELETE eDeleted
#define CC_THREAD_STATE_INVALID eInvalid

typedef int (*cc_component_fun)(void);
typedef struct
{
  int prio; // 0-6
  char name[CC_CONFIG_COMPONENT_NAME_MAX];
  cc_component_fun fun;
} cc_component_main;

// 注册一个线程
void cc_thread_register(cc_tid_fun func, const char *name, int prio,
                        int stack_size);

#define CC_THREAD_REGISTER_ALIAS(func, pro, stack_size, name)         \
  static void __attribute__((constructor)) cc_thread_init##func(void) \
  {                                                                   \
    cc_thread_register(func, name, pro, stack_size);                  \
  }

#define CC_THREAD_REGISTER(func, pro, stack_size) \
  CC_THREAD_REGISTER_ALIAS(func, pro, stack_size, #func)

// 注册一个组件初始化函数
void cc_component_register(cc_component_fun func, int prio, const char *name);

#define CC_INIT_REGISTER_ALIAS(func, prio, name) \
  static void __attribute__((constructor))       \
  cc_device_init_register##func(void)            \
  {                                              \
    cc_component_register(func, prio, name);     \
  }

#define CC_INIT_REGISTER(func, prio) CC_INIT_REGISTER_ALIAS(func, prio, #func)

// 特殊的初始化-因为其他的都要依赖于串口打印，有且只有打印串口调用这个
#define CC_INIT_SERIAL_REGISTER(fn) CC_INIT_REGISTER(fn, 0)
#define CC_INIT_BOARD_REGISTER(fn) CC_INIT_REGISTER(fn, 1)
#define CC_INIT_PREV_REGISTER(fn) CC_INIT_REGISTER(fn, 2)
#define CC_INIT_DEVICE_REGISTER(fn) CC_INIT_REGISTER(fn, 3)
#define CC_INIT_COMPONENT_REGISTER(fn) CC_INIT_REGISTER(fn, 4)
#define CC_INIT_ENV_REGISTER(fn) CC_INIT_REGISTER(fn, 5)
#define CC_INIT_APP_REGISTER(fn) CC_INIT_REGISTER(fn, 6)

void cc_app_start();
void cc_thread_yield();
int cc_is_in_isr();
cc_tid cc_thread_self();

void cc_thread_delete(cc_tid tid);
void cc_thread_delete_by_name(const char *name);
void cc_thread_delete_by_cb(cc_tid_fun fun);

cc_tid cc_get_tid_by_cb(cc_tid_fun fun);
cc_tid cc_get_tid_by_name(const char *name);
cc_tid cc_thread_create_raw(const char *name, size_t stack_size, int prio,
                            cc_tid_fun fun, void *data);
cc_tid cc_thread_create_stack_size(cc_tid_fun fun, int prio, size_t stack_size);
cc_tid cc_thread_create_default(cc_tid_fun fun, int prio);
BaseType_t cc_thread_resume_all(void);
void cc_thread_suspend_all(void);
void cc_thread_resume(cc_tid tid);
void cc_thread_suspend(cc_tid tid);
uint32_t cc_thread_enter_critical(void);
void cc_thread_exit_critical(uint32_t value);

uint32_t cc_thread_get_priority(cc_tid tid);
void cc_thread_set_priority(cc_tid tid, int prio);

uint8_t cc_thread_get_state(cc_tid tid);
uint8_t cc_thread_get_state_by_name(const char *name);
uint8_t cc_thread_get_state_by_cb(cc_tid_fun fun);

uint32_t cc_get_min_stack_using_size(cc_tid tid);
uint32_t cc_get_min_stack_using_size_by_name(const char *name);
uint32_t cc_get_min_stack_using_size_by_cb(cc_tid_fun fun);
#endif